﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StockImport.dataimport.otc.sb;
using StockCommon.data;
using Utilities;
using System.IO;
using StockCommon.Calendar;
using StockCommon.TaskLog;
using HAP = HtmlAgilityPack;
using StockCommon;

namespace StockImport.dataimport.tse.sb
{
    public class TSE_SB_Import : SB_Import_Common
    {
        protected Guid? objectId = null;

        protected override Guid getObjectId()
        {
            if (objectId == null)
                objectId = ObjectExecServices.getServicesId("dateimport", "上市_券商買賣證券日報表", "1.0");
            return (Guid)objectId;
        }

        protected override StockCommon.data.TwnStockMarketType getMarket()
        {
            return TwnStockMarketType.上市;
        }

        protected override void createLog(DateTime date)
        {
            throw new NotImplementedException();
        }

        protected override string getStorePath(DateTime date)
        {
            String r = String.Format(@"D:\SBData\temptse\{0}", DateUtils.toShortDateFormat_NoSlash(date));
            return r;
        }

        public override bool hasSourceData(DateTime date)
        {
            String pa = getStorePath(date);
            if (Directory.Exists(pa))
            {
                String[] fs = Directory.GetFiles(pa);
                if (fs.Length > 600)
                    return true;
            }
            return false;
        }

        protected override int update_internal(DateTime date, bool deleteOld)
        {
            String path = getStorePath(date);
            String[] fs = Directory.GetFiles(path);
            int c=0;
            foreach (String fileName in fs)
            {
                String fn = Path.GetFileName(fileName);
                if (fn.EndsWith(".html") == false)
                    continue;
                int pos = fn.IndexOf(".");
                String code = fn.Substring(0, pos);
                if (updateFromFile(fileName, code, date, false))
                    c++;
            }
            return c;
        }
        /****************************************************************************
         * 
         * 
         * ***************************************************************************/
        protected SBDetail processRow(HAP.HtmlNodeCollection tds, String code,DateTime date)
        {
            
            if (tds == null)
                return null;
            if (tds.Count != 5)
                return null;
            String seqstr = tds[0].InnerText;
            String inststr = tds[1].InnerText;
            String price_str = tds[2].InnerText;
            String buy_str = tds[3].InnerText;
            String sell_str = tds[4].InnerText;

            seqstr = seqstr.Replace("&nbsp;", "").Trim();
            inststr = inststr.Replace("&nbsp;", " ").Trim();
            price_str = price_str.Replace("&nbsp;", "").Trim();
            buy_str = buy_str.Replace("&nbsp;", "").Trim();
            sell_str = sell_str.Replace("&nbsp;", "").Trim();

            if (String.IsNullOrWhiteSpace(seqstr))
                return null;

            if (String.IsNullOrWhiteSpace(inststr))
                return null;

            if (String.IsNullOrWhiteSpace(price_str))
                return null;

            int seq = 0;
            if (int.TryParse(seqstr, out seq) == false)
            {
                return null;
            }

            String instCode = "";
            String instName = "";
            processInst(inststr, out instCode, out instName);

            Guid instId = Guid.Empty;

            SBDetail details = new SBDetail();
            details.sell = 0;
            details.buy = 0;

            if (TradeInstManager.getInstId(instCode, ref  instId))
                details.instId = instId;
            else
                details.instId = TradeInstManager.registerInst(instCode,instName);
 
            details.seq = seq;

            decimal price = new decimal(0);
            if (decimal.TryParse(price_str, out  price))
                details.price = price;
 
            decimal buy = new decimal(0);
            decimal sell = new decimal(0);

            if (decimal.TryParse(buy_str, out buy))
                details.buy=Convert.ToInt32(buy);

            if (decimal.TryParse(sell_str, out sell))
                details.sell= Convert.ToInt32(sell);

            details.日期 = date;
            details.StockCode = code;
            return details;
        }
        /****************************************************************************
         * 
         * 
         * ***************************************************************************/
        protected List<SBDetail> fetchRows(String fileName,String code,DateTime date)
        {
            String content = File.ReadAllText(fileName);

            HAP.HtmlDocument doc = new HAP.HtmlDocument();
            doc.LoadHtml(content);
            HAP.HtmlNodeCollection price_3s = doc.DocumentNode.SelectNodes("//tr[@class='column_value_price_3']");
            HAP.HtmlNodeCollection price_2s = doc.DocumentNode.SelectNodes("//tr[@class='column_value_price_2']");

            List<SBDetail> entries = new List<SBDetail>();

            if (price_3s != null)
                foreach (HAP.HtmlNode price_3 in price_3s)
                {
                    HAP.HtmlNodeCollection tds = price_3.SelectNodes(price_3.XPath + "/td");
                    SBDetail entry = processRow(tds,code,date);                   
                        
                    if (entry != null)
                    {
                        entries.Add(entry);
                    }
                }
            if (price_2s != null)
                foreach (HAP.HtmlNode price_2 in price_2s)
                {
                    HAP.HtmlNodeCollection tds = price_2.SelectNodes(price_2.XPath + "/td");
                    SBDetail entry = processRow(tds,code,date);
                    if (entry != null)
                    {
                        entries.Add(entry);
                    }
                }
            if (entries.Count == 0)
                return null;
            //根據seq sort        
            entries.Sort(new SBDetailComparer());
            return entries;
        }
        public class SBDetailComparer : IComparer<SBDetail>
        {
            public int Compare(SBDetail x, SBDetail y)
            {
                return (int)x.seq -(int) y.seq;
            }
        }
        protected override int updateFromFile_internal(string code, DateTime date, string fileName, Guid taskId)
        {
            try
            {
            List<SBDetail> rows = fetchRows(fileName, code, date);
            if (rows.Count == 0)
                return 0;
            performInsert(code, date, taskId, rows);
            return rows.Count;
            }
            catch (Exception e)
            {
                return -1;
            }
        }
        protected void processInst(String data, out String code, out String inst)
        {
            int pos = data.IndexOf(" ");
            if (pos > 0)
            {
                String s1 = data.Substring(0, pos).Trim();
                String s2 = data.Substring(pos).Trim();
                code = s1;
                inst = s2.Replace("　", "").Replace(" ", "");

            }
            else
            {
                code = data;
                inst = "";
            }
        }

    }
}
